package com.bestcem.xm.user.util.business;

import com.alibaba.fastjson.JSON;
import com.bestcem.xm.componet.redis.service.RedisService;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 用户缓存-Util
 *
 * @author wangyunyun <yunyun.wang@idiaoyan.com>
 * @version v1.0
 * @date 2022/3/1 14:30
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Component
public class UserCacheUtil {

    /**
     * 默认缓存超时时间(一天)
     */
    private static final long DEFAULT_REDIS_CACHED_TIMEOUT = 24 * 60 * 60L;
    ///**
    // * 重置密码设置的token有效时长
    // */
    //public  final long RESET_PASSWORD_TOKEN_TIMEOUT = 2 * 60 * 60L;
    ///**
    // * 重置密码设置的token有效时长
    // */
    //public  final long USER_SET_SKIP_MFA_TIMEOUT = 15 * 24 * 60 * 60L;

    @Autowired
    private RedisService redisService;

    /**
     * 批量添加
     *
     * @param maps
     */
    public void multiSet(Map<String, Integer> maps) {
        redisService.multiSet(maps);
    }

    /**
     * 缓存删除
     *
     * @param keyPattern
     * @param params
     */
    public void delete(String keyPattern, Object... params) {
        redisService.del(buildKey(keyPattern, params));
    }

    /**
     * 缓存删除
     *
     * @param key
     */
    public void delete(String key) {
        redisService.del(key);
    }

    /**
     * 批量删除
     *
     * @param keys
     * @return void
     */
    public void delete(List<String> keys) {
        redisService.del(keys);
    }

    /**
     * 获取redis值
     *
     * @param keyPattern
     * @param params
     * @return
     */
    public String get(String keyPattern, Object... params) {
        String key = buildKey(keyPattern, params);
        return redisService.get(key) == null ? null : redisService.get(key).toString();
    }

    /**
     * 通过key获取特定类型的redis值
     *
     * @param key
     * @param clazz
     * @return
     */
    public <T> T get(String key, Class<T> clazz) {
        Object value = redisService.get(key);
        if (Objects.nonNull(value)) {
            return JSON.parseObject(value.toString(), clazz);
        }

        return null;
    }

    /**
     * redis缓存值 自增长1操作
     *
     * @param keyPattern
     * @param params
     * @return
     */
    public Long incrBy(String keyPattern, Object... params) {
        String key = buildKey(keyPattern, params);
        return redisService.incr(key, 1);
    }

    /**
     * redis缓存值 自增长1操作
     *
     * @param key
     * @return
     */
    public Long incrByKey(String key) {
        return redisService.incr(key, 1);
    }

    /**
     * 将值 value 关联到 key ，并将 key 的过期时间设为 timeout
     *
     * @param key
     * @param value
     * @param timeout
     * @param unit
     */
    public void setEx(String key, String value, long timeout, TimeUnit unit) {
        redisService.set(key, value, timeout, unit);
    }

    /**
     * 将值 value 关联到 key ，并将 key 的过期时间设为 timeout
     *
     * @param key
     * @param value
     * @param timeout
     */
    public void setEx(String key, Object value, long timeout) {
        redisService.set(key, JSON.toJSONString(value), timeout, TimeUnit.SECONDS);
    }

    /**
     * 将值 value 关联到 key. 过期时间: 默认缓存超时时间 过期时间单位: 默认为秒
     *
     * @param key
     * @param value
     */
    public void setEx(String key, String value) {
        setEx(key, value, DEFAULT_REDIS_CACHED_TIMEOUT, TimeUnit.SECONDS);
    }

    /**
     * 设置过期时间 单位 秒
     *
     * @param key
     * @param timeout
     * @return
     */
    public Boolean expire(String key, long timeout) {
        return redisService.expire(key, timeout, TimeUnit.SECONDS);
    }

    /**
     * 设置过期时间 单位 秒
     *
     * @param keyPattern key
     * @param timeout    过期时间，单位s
     * @param params     key中的变量内容
     * @return java.lang.Boolean
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/03/08 17:39
     */
    public Boolean expire(String keyPattern, long timeout, Object... params) {
        return redisService.expire(buildKey(keyPattern, params), timeout, TimeUnit.SECONDS);
    }

    /**
     * 设置key值
     *
     * @param pattern
     * @param params
     * @return
     */
    public String buildKey(String pattern, Object... params) {
        if (params == null) {
            return pattern;
        }
        return MessageFormat.format(pattern, params);
    }

    /**
     * 从头部添加list元素
     *
     * @param key
     * @param value
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @version v1.0
     * @date 2022/3/8 17:42
     */
    public void leftPush(String key, String value) {
        redisService.lLeftPush(key, value);
    }

    /**
     * 移出并获取列表的第一个元素
     *
     * @param key
     * @return String
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @version v1.0
     * @date 2022/3/14 17:08
     */
    public String leftPop(String key) {
        Object ret = redisService.lLeftPop(key);
        return ret != null ? ret.toString() : null;
    }

    /**
     * 是否存在key
     *
     * @param key
     * @return
     */
    public Boolean hasKey(String key) {
        return redisService.hasKey(key);
    }

    /**
     * 设值 如果不存在
     *
     * @param key
     * @param value
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @version v1.0
     * @date 2022/3/11 18:20
     */
    public void setIfAbsent(String key, Object value) {
        redisService.setIfAbsent(key, value);
    }
}
